﻿using System;
using System.Collections.Generic;
using AccesoDatos.IDAO;
using Entidades;
using log4net;
using NHibernate;


namespace AccesoDatos.DAO
{
    public class DaoCategoria : IDaoCategoria
    {
        protected static readonly ILog log = LogManager.GetLogger(typeof(DaoCategoria));

        
        /// <summary>
        /// Metodo que me retorna un IList de todas las categorias 
        /// que se encuentran en la bd  
        /// </summary>
        
        public IList<Categoria> SeleccionarTodos()
        {
            try
            {
                log4net.Config.XmlConfigurator.Configure();
                log.Info("Entra en el metodo SeleccionarTodos");
                ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
                sesion.BeginTransaction();
                IQuery query = sesion.CreateQuery("from Categoria");
                IList<Categoria> retorna = (IList<Categoria>) query.List<Categoria>();
                sesion.Transaction.Commit();
                log.Info("Lista de categorias retornada");
                return retorna;
            }
            catch (ADOException exception)
            {
                log.Error("se ha producido un error en la seleccion de categorias");
                log.Error(exception.Message);
            }
            return null;
        }


        /// <summary>
        /// Metodo que retorna un objeto de tipo categoria
        /// y recibe el id del mismo para la posterior busqueda
        /// </summary>
        
        public Categoria SeleccionarPorId(int id)
        {
            try {
                log4net.Config.XmlConfigurator.Configure();
                log.Info("Entra al metodo SeleccionarPorId recibiendo el valor: "+id);
                ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
                sesion.BeginTransaction();
                Categoria busqueda = (Categoria)sesion.Get(typeof(Categoria), id);
                sesion.Transaction.Commit();
                log.Info("Categoria retornada con éxito");
            return busqueda;
                }catch(ADOException exception)
                {
                    log.Error("se ha producido un error en la seleccion de categoria por id");
                    log.Error(exception.Message);
                }

            return null;
        }

        /// <summary>
        /// Metodo que retorna un objeto de tipo categoria
        /// y recibe el id del mismo para la posterior busqueda
        /// </summary>
        public Categoria CategoriaPorId(int id)
        {
            try
            {
                log4net.Config.XmlConfigurator.Configure();
                log.Info("Entra al metodo CategoriaPorId recibiendo el valor: " + id);
            ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
            sesion.BeginTransaction();
            Categoria busqueda = (Categoria)sesion.Get(typeof(Categoria), id);
            sesion.Transaction.Commit();
            log.Info("Objeto Categoria retornado con éxito");
            return busqueda;
                }catch(ADOException exception)
                {
                    log.Error("se ha producido un error en la seleccion de categoria por id");
                    log.Error(exception.Message);
                }

            return null;
        }

        /// <summary>
        /// Metodo que recibe como parameto el objeto completo
        /// de categoria y lo agrega en la bd
        /// </summary>
        public void Insertar(Categoria c)
        {
            log4net.Config.XmlConfigurator.Configure();
            ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
            ITransaction transaccion = null;
            try
            {
                transaccion = sesion.BeginTransaction();
                sesion.Save(c);
                transaccion.Commit();
                sesion.Flush();
                log.Warn("Objeto Categoria agregado con éxito");

            }
            catch (ADOException e)
            {
                e.GetBaseException();
                if (transaccion != null)
                {
                    log.Info("no se pudo agregar la categoría");
                    log.Info(e.Message);
                    transaccion.Rollback();
                    throw;

                }
            }

        }


        /// <summary>
        /// Metodo que recibe el objeto que desea modificar 
        /// y lo setea con los valores tomados del formulario
        /// modificar categoria
        /// </summary>
        
        public void Modificar(Categoria c)
        {
            try
            {
                    log4net.Config.XmlConfigurator.Configure();
                    log.Info("Entra en el método modificar recibiendo id: "+c.IdCategoria+" nombre: "+c.Nombre);
                    ConfiguracionNHibernate.CloseSession();
                    ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
                    sesion.BeginTransaction();
                    sesion.Update(c);
                    sesion.Transaction.Commit();
                    log.Warn("Objeto Categoria modificado con exito");
                }catch(ADOException exception)
                {
                    log.Error("se ha producido un error en la modificación de categoría");
                    log.Error(exception.Message);
                }


        }
        /// <summary>
        /// Metodo que recibe el id de la categoria que desea eliminar
        /// </summary>
       
        public void EliminarPorId(int id)
        {
            try
            {
                log4net.Config.XmlConfigurator.Configure();
                log.Info("Entra en el método EliminarPorId recibiendo id: " +id);
                ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
                sesion.BeginTransaction();
                sesion.Delete((Categoria) sesion.Get(typeof (Categoria), id));
                sesion.Transaction.Commit();
                log4net.Config.XmlConfigurator.Configure();
                log.Warn("Objeto Categoria eliminado con exito");
            }catch(NHibernate.ADOException adoException){
                    log.Error("Error al eliminar Categoria");
                    log.Error(adoException.Message);
            }
        }


        public IList<Categoria> SeleccionarPorParametro(string parametro, string valor)
        {
            try{
                    log4net.Config.XmlConfigurator.Configure();    
                    log.Info("Entra en el metodo SeleccionarPorParametro recibiendo: parametro: "+parametro+ " valor:"+valor);
                    ISession sesion = ConfiguracionNHibernate.GetCurrentSession();
                    sesion.BeginTransaction();
                    IQuery query = sesion.CreateQuery("from Categoria where " + parametro + " = '" + valor + "'");
                    IList<Categoria> retorna = (IList<Categoria>)query.List<Categoria>();
                    sesion.Transaction.Commit();
                    log.Info("Se retorno la lista de categorias que cumplen con el parametro");
                     return retorna;

            }catch(ADOException exception)
                {
                    log.Error("Error al seleccionar Categoria por parametro");
                    log.Error(exception.Message);
                }
            return null;
        }
    }
}
